﻿using Xejen.Ipc.Framework.Controllers;
using Xejen.Ipc.Framework.Steps;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Xejen.Ipc.Framework.Flows
{
    /// <summary>
    /// 表示工业控制流
    /// </summary>
    /// <typeparam name="TData">流转数据，将会在流程启动时创建此数据的对象，并在整个生命周期中流转</typeparam>
    /// <creator>marc</creator>
    public interface IFlow<TData>
        where TData : new()
    {
        /// <summary>
        /// 控制流的唯一Id
        /// </summary>
        int Id { get; }
        /// <summary>
        /// 控制流的名称
        /// </summary>
        string Name { get; }

        /// <summary>
        /// 父流程
        /// </summary>
        IFlow<TData> Parent { get; }

        /// <summary>
        /// <inheritdoc cref="IFlow{TData}" path="/typeparam[@name='TData']"/>
        /// </summary>
        TData Data { get; }

        /// <inheritdoc cref="FlowStatus"/>
        FlowStatus Status { get; }

        /// <summary>
        /// 日志
        /// </summary>
        ILogger Logger { get; }
        /// <summary>
        /// 线程令牌
        /// </summary>
        CancellationToken CancellationToken { get; }

        /// <summary>
        /// 流程控制器列表
        /// </summary>
        IReadOnlyList<IController<TData>> Controllers { get; }

        /// <summary>
        /// 流程启动时的事件
        /// </summary>
        event EventHandler<FlowEventArgs<TData>> Started;
        /// <summary>
        /// 流程暂停时的事件
        /// </summary>
        event EventHandler<FlowEventArgs<TData>> Paused;
        /// <summary>
        /// 流程恢复时的事件
        /// </summary>
        event EventHandler<FlowEventArgs<TData>> Resumed;
        /// <summary>
        /// 流程停止时的事件
        /// </summary>
        event EventHandler<FlowEventArgs<TData>> Stopped;
        /// <summary>
        /// 流程发生错误时的事件
        /// </summary>
        event EventHandler<ErrorEventArgs<TData>> Error;
        /// <summary>
        /// 循环周期结束时的事件
        /// </summary>
        event EventHandler<FlowEventArgs<TData>> CycleCompleted;
        /// <summary>
        /// 扫描周期时长的监控，当检测到扫描周期时长大于设定值<see cref="IpcHostConfig.ScanIntervalThreshold"/>时，将引发此事件
        /// </summary>
        event EventHandler<ScanIntervalExceededEventArgs<TData>> ScanIntervalExceeded;

        /// <summary>
        /// 启动
        /// <para>
        /// 流程循环次数将以配置<see cref="IpcHostConfig.LoopCount"/>为准，若该值小于0，将无限循环
        /// </para>
        /// </summary>
        /// <param name="cancellationToken">线程令牌，若传值为default，则子流程将自动使用父流程的线程令牌</param>
        void Start(CancellationToken cancellationToken = default);
        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="loopCount">循环次数</param>
        /// <param name="cancellationToken">线程令牌，若传值为default，则子流程将自动使用父流程的线程令牌</param>
        void Start(int loopCount, CancellationToken cancellationToken = default);
        /// <summary>
        /// 暂停
        /// </summary>
        void Pause();
        /// <summary>
        /// 继续
        /// </summary>
        void Resume();
        /// <summary>
        /// 结束
        /// </summary>
        void Stop();
    }
}
